package astudy.networking.tcp;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang.StringUtils;

public class CommandThread implements Runnable{

	private Socket client;
	private File currentDir;
	
	public CommandThread(Socket client) {
		this.client = client;
		this.currentDir = new File(System.getProperty("user.dir"));
	}
	
	public void run() {

		try {
			BufferedReader is = new BufferedReader(new InputStreamReader(client.getInputStream()));
			PrintWriter os= new PrintWriter(client.getOutputStream());
			String line = null;
			while ((line = is.readLine()) != null) {
				String[] tmp = line.trim().split("\\s+");
				if (tmp.length == 0) {
					//do nothing
				} else {
					String cmd = tmp[0];
					String[] args = new String[tmp.length-1];
					System.arraycopy(tmp, 1, args, 0, args.length);
					String result = null;
					if ("quit".equalsIgnoreCase(cmd)) {
						os.println("quit");
						os.flush();
						break;
					} else if ("cd".equalsIgnoreCase(cmd)) {
						result = cd(args);
						os.println(result);
						os.flush();
					} else if ("dir".equalsIgnoreCase(cmd)) {
						result = dir(args);
						os.println(result);
						os.flush();
					} else if ("get".equalsIgnoreCase(cmd)) {
						FileSender fileSender = get(args);
						os.println(fileSender.getLocalPort());
						os.flush();
						fileSender.send();
					} else {
						result = "Unknown Command: " + line;
						os.println(result);
						os.flush();
					}
				}
			}
			is.close();
			os.close();
			client.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * download file
	 * @param args
	 * @return
	 */
	private FileSender get(String[] args) {
		
		try {
			if (args.length < 2) {
				throw new RuntimeException("You should specified file names.");
			} else {
				String path = args[0];
				File file = new File(this.currentDir.getAbsolutePath(), path);
				if (file.exists()) {
					if (file.isDirectory()) {
						throw new RuntimeException(path + " is not a file!");
					} else {
						return new FileSender(file);

					}
				} else {
					throw new RuntimeException(path + " does not exist!");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private String cd(String[] args) {
		
		try {
			if (args.length != 1) {
				throw new RuntimeException("Bad command parameter.");
			} else {
				String path = args[0];
				File dir = new File(this.currentDir.getAbsolutePath(), path);
				if (dir.exists()) {
					if (dir.isDirectory()) {
						URI p = new URI(dir.getAbsolutePath().replace("\\", "/"));
						this.currentDir = new File(p.normalize().toString());
						return "Current Directory: " + this.currentDir.getAbsolutePath();
					} else {
						throw new RuntimeException(path + " is not a directory!");
					}
				} else {
					throw new RuntimeException(path + " does not exist!");
				}
			}
		} catch (Exception e) {
			return "Error: " + e.getMessage();
		}
	}

	private String dir(String[] args) {
		
		File[] files = this.currentDir.listFiles();
		List<String> temp = new ArrayList<String>();
		temp.add("[.]");
		temp.add("[..]");
		for (File file: files) {
			if (file.isDirectory()) {
				temp.add("[" + file.getName() + "]");
			} else {
				temp.add(file.getName());
			}
		}
		String[] names = temp.toArray(new String[temp.size()]);
		Arrays.sort(names);
		return StringUtils.join(names, "\\n");
	}
}
